﻿using System;
using System.ComponentModel;
using System.Net;
using System.Text;
using System.Threading;
using System.Xml;
using DVDFilmoteka.Forms;
using DVDFilmoteka.Settings;

namespace DVDFilmoteka.UpdateManagement
{
    class ApplicationUpdater
    {
        private static readonly ApplicationUpdater instance = new ApplicationUpdater();

        private const String fileSite = "http://filmoteka.aspweb.cz/Files/";
        private const String updateSite = "http://filmoteka.aspweb.cz/Download.aspx";
        private readonly WebClient webClient;
        public Form1 ParentForm { get; set; }
        private String tempFile;
        private DownloadProgress progressForm = null;
        private object parentState;

        /// <summary>
        /// Factory method
        /// </summary>
        /// <returns></returns>
        public static ApplicationUpdater getInstance()
        {
            return instance;
        }

        /// <summary>
        /// konstruktor
        /// </summary>
        private ApplicationUpdater()
        {
            webClient = new WebClient();
            webClient.Encoding = Encoding.UTF8;
            webClient.DownloadDataCompleted += downloadDataCompleted;
            webClient.DownloadFileCompleted += downloadFileCompleted;

            SettingsManager manager = SettingsManager.Instance;
            if (manager.UseProxy)
            {
                if (manager.UseDefaultProxy)
                {
                    webClient.Proxy = WebRequest.GetSystemWebProxy();
                } else
                {
                    IWebProxy proxy = new WebProxy(manager.ProxyIPAddress.ToString(), manager.ProxyPort);
                    webClient.Proxy = proxy;
                }
            }
        }

        /// <summary>
        /// Zjisti aktualni verzi (asynchronne)
        /// </summary>
        public void checkNewVersionAsync(object state)
        {
            parentState = state;

            webClient.DownloadDataAsync(new Uri(updateSite));
        }

        private void downloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
        {
            if (!e.Cancelled && e.Error == null)
            {
                byte[] data = e.Result;
                string textData = webClient.Encoding.GetString(data);

                int pos = textData.IndexOf("Aktuální verze je ");
                String versionText = textData.Substring(pos + 18, 3);
                
                try
                {
                    Version actualVersion = new Version(versionText);
                    String version = Form1Servant.AssemblyVersion;
                    if (version.Contains("beta")) version = version.Substring(0, 3);
                    Version myVersion = new Version(version);

                    if (actualVersion > myVersion) // Porovna verze
                    {
                        ParentForm.newVersionAvailable(actualVersion, parentState);
                    } else
                    {
                        // Overi betaverze
                        if (SettingsManager.Instance.BetaInform && !Form1Servant.AssemblyVersion.Contains("beta"))
                        {
                            if (textData.IndexOf("Je k dispozici betaverze!") != -1)
                            {
                                ParentForm.betaVersionAvailable(parentState);
                            }
                        }

                        ParentForm.newVersionNotAvailable(actualVersion, parentState);
                    }
                } catch (Exception) {}
            }
        }

        /// <summary>
        /// Stahne asynchronne soubor z internetu
        /// </summary>
        /// <param name="version"></param>
        /// <param name="form"></param>
        public void downloadNewVersionAsync(Version version, DownloadProgress form)
        {
            if (version == null || form == null) return;

            progressForm = form;
            progressForm.FormClosed += parentFormClosing;

            String tempDir = Environment.GetEnvironmentVariable("TEMP");
            if (String.IsNullOrEmpty(tempDir))
            {
                tempDir = Environment.GetEnvironmentVariable("TMP");
            }

            if (String.IsNullOrEmpty(tempDir))
            {
                tempDir = Environment.SpecialFolder.ApplicationData.ToString();
            }

            tempFile = tempDir + "\\Setup" + version + ".exe";
            
            webClient.DownloadProgressChanged += form.downloadProgressChanged;
            webClient.DownloadFileAsync(new Uri(fileSite + "Setup" + version + ".exe"), tempFile);

            form.ShowDialog(ParentForm);
        }

        private void parentFormClosing(object sender, EventArgs e)
        {
            webClient.CancelAsync();
        }

        private void downloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (!e.Cancelled && e.Error == null && !String.IsNullOrEmpty(tempFile))
            {
                progressForm.Close();
                Thread.Sleep(100);
                ParentForm.newVersionDownloaded(tempFile);
            }

            tempFile = null;
        }
    }
}